package com.lear.rrbus.view;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.http.util.EncodingUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Parcelable;
import android.os.StrictMode;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.lear.rrbus.R;
import com.lear.rrbus.data.LineInfo;
import com.lear.rrbus.data.StationInfo;
import com.lear.rrbus.utils.StationInfoAdapter;
import com.lear.rrbus.utils.Utils;

@SuppressLint("WorldReadableFiles")
public class BusResultView extends Activity implements OnClickListener {

	private class LoadingThread implements Runnable {
		public void run() {
			try {
				if (Utils.DEBUG) {
					String time = DateFormat.format("kk:mm:ssss",
							System.currentTimeMillis()).toString();
					Log.v(Utils.TAG, "Parse begin time:" + time);
				}
				// if (Utils.DEBUG) {
				// doc = Jsoup.parse(
				// BusResultView.this.getAssets().open("bus.html"),
				// "UTF-8", "http://gzbusnow.sinaapp.com/");
				// } else {
				doc = Jsoup.connect(urlString).timeout(Utils.TIMEOUT * 1000)
						.get();
				// }
				if (Utils.DEBUG) {
					String time2 = DateFormat.format("kk:mm:ssss",
							System.currentTimeMillis()).toString();
					Log.v(Utils.TAG, "Parse finish time:" + time2);
				}

				Message msg = updateUI.obtainMessage();
				msg.what = Utils.UPDATEUI;
				updateUI.sendMessage(msg);

				// Loading succeed when here
				if (pDialog.isShowing()) {
					pDialog.cancel();
				}

			} catch (Exception e) {
				// Loading failed
				if (e.getCause() != null)
					Log.e(Utils.TAG, e.getCause().toString());

				else
					Log.e(Utils.TAG, e.toString());
				pDialog.cancel();
				showString = getResources()
						.getString(R.string.hint_load_failed);
				Message msg = updateUI.obtainMessage();
				msg.what = Utils.DISPLAYTOAST;
				updateUI.sendMessage(msg);
				finish();
			}
		}
	}

	private class UiHandler extends Handler {
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case Utils.UPDATEUI:
				// Ask the user to select a line when there is more than one
				// line
				boolean isNeedLoadLine = prefs.getBoolean(Utils.NEEDLOADLINE,
						false);
				if (isNeedLoadLine) {
					if (parseLines() > 1) {
						showLines();
					} else if (!parseDetail()) {
						finish();
					}
				}
				// Otherwise, load now
				else if (!parseDetail()) {
					finish();
				}
				break;
			case Utils.DISPLAYTOAST:
				Toast.makeText(BusResultView.this, showString,
						Toast.LENGTH_SHORT).show();
				break;
			case Utils.REFRESH:
				getBusInfo();
			default:
				break;
			}

		}
	}

	private Context context;
	private SharedPreferences prefs;

	private Timer rfTimer;
	private TimerTask rfTask;
	private boolean isAuto = Utils.ISAUTOREF;

	private View customView;
	private ImageButton btnBack;
	private ImageButton btnRef;
	private ImageButton btnShare;
	private ListView lsBusView;
	private TextView txLineDetail;
	private UiHandler updateUI;
	private ProgressView pDialog;
	private LinearLayout layoutLine;

	private LinearLayout toastLayout;
	private View toastView;
	private TextView toastInfo;

	private Document doc;
	private String urlString;
	private int whichTable = 0;
	private String showString = "";
	private List<LineInfo> lineList;
	private List<StationInfo> stationList;
	private StationInfoAdapter adapter;

	private int selected = 0;
	private String storedStation = "";
	private String storedLine = "";
	private String toastString = "";
	private int distant = 0;
	private int nearest = 0;
	private int currentIndex = 0;
	private boolean userScrolled = false;

	private int alarmCount;
	private Notification noti;
	private NotificationManager nManager;
	private PendingIntent pIntent;
	private long[] vPattern = new long[] { 500, 300, 0, 0 };

	private Handler myHandler;
	private LoadingThread loading;

	private boolean checkIntent(String input) {
		return input.contains("qzone") || input.contains("mm")
				|| input.contains("mms") || input.contains("weibo")
				|| input.contains("mail") || input.contains("weibo");
	}

	private void getBusInfo() {
		pDialog.show();

		// 新建Handler线程
		HandlerThread handlerThread = new HandlerThread("SEARCH_THREAD");
		// 启动线程
		handlerThread.start();
		// 获取线程的Looper环
		Looper looper = handlerThread.getLooper();
		// 新建Handler
		myHandler = new Handler(looper);
		// 新建用户线程
		loading = new LoadingThread();
		// 把用户线程post到新建的线程
		myHandler.post(loading);

		// Thread retriveThread = new Thread(new LoadingThread());
		// retriveThread.start();
	}

	@SuppressWarnings("unused")
	private String getFromAssets(String fileName) {
		String result = "";
		try {
			InputStream in = getResources().getAssets().open(fileName);
			int lenght = in.available();
			byte[] buffer = new byte[lenght];
			in.read(buffer);
			result = EncodingUtils.getString(buffer, Utils.ENCODING);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	private int handleIndex() {
		int tempIndex = 0;
		for (StationInfo station : stationList) {
			if (station.getName().equals(storedStation)) {
				currentIndex = station.getIndex();
				tempIndex = currentIndex - Utils.SCROLLS;
				selected = tempIndex < 0 ? 0 : tempIndex;
				break;
			}
		}
		return -1;
	}

	private boolean handleNotify() {
		int distant = 0;
		List<StationInfo> tempStationList = new ArrayList<StationInfo>();
		for (StationInfo station : stationList) {
			distant = currentIndex - station.getIndex();
			if (distant >= 0 & distant <= alarmCount
					& !TextUtils.isEmpty(station.getBusCount())) {
				tempStationList.add(station);
			}
		}

		if (!tempStationList.isEmpty()) {
			StationInfo station = tempStationList
					.get(tempStationList.size() - 1);
			distant = currentIndex - station.getIndex();
			noti = new Notification.Builder(this)
					.setContentText(
							station.getTimeString() + "距离【" + distant + "】站")
					.setContentTitle(
							getResources().getString(R.string.hint_found_car))
					.setSmallIcon(R.drawable.prompt).setVibrate(vPattern)
					.setContentIntent(pIntent)
					.setDefaults(Notification.DEFAULT_SOUND).getNotification();
			nManager.cancel(0);
			nManager.notify(0, noti);
		}
		return false;
	}

	private void handleToast() {
		nearest = -1;
		distant = 0;
		int currentStation = 0;

		for (StationInfo station : stationList) {
			if (station.getName().equals(storedStation)) {
				currentStation = station.getIndex();
				currentStation--;
				break;
			}
		}

		for (int i = currentStation; i >= 0; i--) {
			if (!TextUtils.isEmpty(stationList.get(i).getBusCount())) {
				nearest = i;
				break;
			}
		}

		if (nearest > 0) {
			distant = currentStation - nearest;
			Toast toast = Toast.makeText(BusResultView.this, null,
					Toast.LENGTH_LONG);
			toastString = stationList.get(nearest).getTimeString() + "发现车辆"
					+ "距离【" + distant + "】站";
			toastInfo.setText(toastString);
			toast.setView(toastLayout);
			toast.setGravity(Gravity.FILL_HORIZONTAL | Gravity.TOP, 0, 0);
			toast.show();
		}
	}

	private void initialData() {
		prefs = getSharedPreferences(Utils.APPNAME, Context.MODE_WORLD_READABLE);
		urlString = prefs.getString(Utils.SEARCHKEY, "");
		if (urlString == null) {
			Toast.makeText(BusResultView.this,
					getResources().getString(R.string.hint_search_failed),
					Toast.LENGTH_SHORT).show();
			finish();
		} else if (urlString.isEmpty()) {
			Toast.makeText(BusResultView.this,
					getResources().getString(R.string.hint_search_failed),
					Toast.LENGTH_SHORT).show();
			finish();
		}

		updateUI = new UiHandler();
		lineList = new ArrayList<LineInfo>();
		stationList = new ArrayList<StationInfo>();

		nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		pIntent = PendingIntent.getActivity(this, 0, new Intent(this,
				BusResultView.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP),
				PendingIntent.FLAG_CANCEL_CURRENT);

		alarmCount = prefs.getInt(Utils.STOREDALAEM, -1);
		storedStation = prefs.getString(Utils.STOREDSTATION, null);
	}

	private void initialToast() {
		LayoutInflater inflater = LayoutInflater.from(this);
		toastView = inflater.inflate(R.layout.bus_toast, null);
		toastLayout = (LinearLayout) toastView.findViewById(R.id.toast_layout);
		toastInfo = (TextView) toastView.findViewById(R.id.toast_info);
	}

	/**
	 * 初始化视�?
	 */
	private void initialView() {
		layoutLine = (LinearLayout) findViewById(R.id.layout_line);
		lsBusView = (ListView) findViewById(R.id.ls_bus_list);
		btnRef = (ImageButton) findViewById(R.id.btn_refresh2);
		btnBack = (ImageButton) findViewById(R.id.btn_backline);
		btnShare = (ImageButton) findViewById(R.id.btn_share);
		txLineDetail = (TextView) findViewById(R.id.tx_line_detail);

		btnRef.setOnClickListener(this);
		btnBack.setOnClickListener(this);
		btnShare.setOnClickListener(this);

		pDialog = new ProgressView(this);
		pDialog.setIndeterminate(true);
		pDialog.setCancelable(true);
		selected = 0;

		lsBusView.setOnScrollListener(new OnScrollListener() {
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
			}

			public void onScrollStateChanged(AbsListView view, int scrollState) {
				// Save the current selected item in order to return to it when
				// scrolled over
				if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
					userScrolled = true;
					selected = lsBusView.getFirstVisiblePosition();
				}
			}
		});

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_refresh2:
			getBusInfo();
			break;
		case R.id.btn_backline:
			selected = 0;
			userScrolled = false;
			whichTable = whichTable == 0 ? 1 : 0;
			getBusInfo();
			break;
		case R.id.btn_share:
			shareInfo();
			break;
		default:
			break;
		}
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (true)
			StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
					.detectNetwork().penaltyLog().build());
		StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
				.detectLeakedSqlLiteObjects().penaltyLog().penaltyDeath()
				.build());
		setActionBar();
		setContentView(R.layout.bus_result_view);
		context = this;

		initialView();
		initialToast();
		initialData();
		getBusInfo();
		runRefresh();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.bus_result_view, menu);
		return true;
	}

	public void onDestroy() {
		super.onDestroy();
		myHandler.removeCallbacks(loading);
		if (pDialog.isShowing()) {
			pDialog.cancel();
		}
		if (rfTimer != null) {
			isAuto = false;
			rfTask.cancel();
			rfTimer.cancel();
		}
		nManager.cancel(0);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_bus_auto:
			isAuto = true;
			Toast.makeText(BusResultView.this,
					getResources().getString(R.string.hint_autorefresh),
					Toast.LENGTH_SHORT).show();
			break;
		case R.id.menu_bus_stop:
			isAuto = false;
			Toast.makeText(BusResultView.this,
					getResources().getString(R.string.hint_unautorefresh),
					Toast.LENGTH_SHORT).show();
			break;
		case android.R.id.home:
			onBackPressed();
			break;
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		MenuItem menuAuto = menu.findItem(R.id.menu_bus_auto);
		MenuItem menuStop = menu.findItem(R.id.menu_bus_stop);

		menuAuto.setVisible(!isAuto);
		menuStop.setVisible(isAuto);

		return true;
	}

	@SuppressWarnings("unused")
	private boolean parseDetail() {
		if (Utils.DEBUG)
			Log.v(Utils.TAG, "Parsing detail 1.");
		prefs.edit().putBoolean(Utils.NEEDLOADLINE, false).commit();

		parseTitle();
		parseLineInfo();
		stationList.clear();
		int index = 1;
		if (doc.getElementsByTag("table").size() == 0) {
			showString = getResources().getString(R.string.hint_load_failed);
			Message msg = updateUI.obtainMessage();
			msg.what = Utils.DISPLAYTOAST;
			updateUI.sendMessage(msg);
			return false;
		}

		if (Utils.DEBUG)
			Log.v(Utils.TAG, "Parsing detail 2.");

		// Read the first table
		Element table1 = doc.getElementsByTag("table").get(whichTable);
		// Read all the line
		Elements rows = table1.getElementsByTag("tr");
		List<String> stations = new ArrayList<String>();

		if (Utils.DEBUG)
			Log.v(Utils.TAG, "Parsing detail 3.");
		// Read every line
		for (Element column : rows) {
			// Read all the column
			Elements cells = column.getElementsByTag("td");
			// Read the first column
			Element columnCount = cells.get(0);
			String count = columnCount.ownText().trim().replace(" ", "");
			// Read the second column
			Element columnStop = cells.get(1);
			// Splite
			String[] stops = columnStop.ownText().split(" ");
			// Station name
			String stop = stops[0].replace(" ", "");
			// Link
			String link = columnStop.getElementsByTag("a").get(0).attributes()
					.get("href").toString();

			stationList.add(new StationInfo(stop, index++, count, link));
		}

		if (Utils.DEBUG)
			Log.v(Utils.TAG, "Parsing detail 4.");
		adapter = new StationInfoAdapter(this, R.layout.bus_list_row,
				stationList);
		lsBusView.setAdapter(adapter);
		lsBusView.setCacheColorHint(0);
		adapter.notifyDataSetChanged();

		if (Utils.DEBUG)
			Log.v(Utils.TAG, "Parsing detail 5.");
		if (!userScrolled) {
			handleIndex();
		}
		lsBusView.setSelection(selected);
		if (alarmCount > 0) {
			handleNotify();
		}
		handleToast();

		return true;
	}

	private int parseLines() {
		lineList.clear();
		Elements lines = doc.getElementsByTag("li");
		int size = lines.size();
		if (size != 0) {
			for (Element element : lines) {
				StringBuffer link = new StringBuffer();
				link.append("http://gzbusnow.sinaapp.com/");
				link.append(element.getElementsByTag("a").get(0).attributes()
						.get("href").toString());
				lineList.add(new LineInfo(element.text(), link.toString()));
			}
		}

		lineList.add(new LineInfo(doc.title().split("结果")[0], urlString));
		return lineList.size();
	}

	private void parseLineInfo() {
		Element lineDetail = doc.select("div.bus_direction").first();
		if (lineDetail != null) {
			txLineDetail.setText(lineDetail.text());
			layoutLine.setVisibility(View.VISIBLE);
		}
	}

	private void parseTitle() {
		// Custom the title
		String title = doc.title();
		if (title.contains("结果")) {
			this.setTitle(title.split("结果")[0]);
		} else if (title.contains("信息")) {
			this.setTitle(title.split("信息")[0]);
		}
	}

	private void runRefresh() {
		if (rfTimer != null) {
			isAuto = false;
			rfTask.cancel();
			rfTimer.cancel();
		}

		if (isAuto) {
			rfTimer = new Timer();
			rfTask = new TimerTask() {
				@Override
				public void run() {
					if (isAuto) {
						Message msg = updateUI.obtainMessage();
						msg.what = Utils.REFRESH;
						updateUI.sendMessage(msg);
					}
				}
			};
			rfTimer.schedule(rfTask, Utils.AUTOTIME * 1000,
					Utils.AUTOTIME * 1000);
		}
	}

	private void setActionBar() {
		ActionBar mActionBar = getActionBar();
		mActionBar.setDisplayShowHomeEnabled(false);
		mActionBar.setDisplayHomeAsUpEnabled(true);
		mActionBar.setDisplayShowCustomEnabled(true);

		customView = getLayoutInflater().inflate(R.layout.custom_view2, null);
		mActionBar.setCustomView(customView, new ActionBar.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
				Gravity.RIGHT | Gravity.CENTER_VERTICAL));
	}

	private void shareInfo() {
		storedLine = prefs.getString(Utils.STOREDLINE, "未知线路");
		String shareInfo = "我在【" + storedStation + "】等待【" + storedLine
				+ "】最近一辆车在【" + stationList.get(nearest).getTimeString()
				+ "】距离【" + distant + "】站";

		String contentDetails = shareInfo;
		String contentBrief = shareInfo;
		String shareUrl = "http://www.weibo.com/nifa";

		Intent intent = new Intent(Intent.ACTION_SEND);
		intent.setType("text/plain");
		intent.putExtra(Intent.EXTRA_TEXT, shareInfo);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

		// 过滤intent
		List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(
				intent, 0);
		if (!resInfo.isEmpty()) {
			List<Intent> targetedShareIntents = new ArrayList<Intent>();
			for (ResolveInfo info : resInfo) {
				Intent targeted = new Intent(Intent.ACTION_SEND);
				targeted.setType("text/plain");
				ActivityInfo activityInfo = info.activityInfo;
				if (!(checkIntent(activityInfo.packageName) || checkIntent(activityInfo.name))) {
					continue;
				}
				if (activityInfo.packageName.contains("gm")
						|| activityInfo.name.contains("mail")) {
					targeted.putExtra(Intent.EXTRA_TEXT, contentDetails);
				} else if (activityInfo.packageName.contains("zxing")) {
					targeted.putExtra(Intent.EXTRA_TEXT, shareUrl);
				} else {
					targeted.putExtra(Intent.EXTRA_TEXT, contentBrief);
				}
				if (isAuto) {

				}
				targeted.setPackage(activityInfo.packageName);
				targetedShareIntents.add(targeted);
			}

			Intent chooserIntent = Intent.createChooser(
					targetedShareIntents.remove(0), "Select app to share");
			if (chooserIntent == null) {
				return;
			}

			chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
					targetedShareIntents.toArray(new Parcelable[] {}));
			try {
				startActivity(chooserIntent);
			} catch (android.content.ActivityNotFoundException ex) {
				Toast.makeText(this, "Can't find share component to share",
						Toast.LENGTH_SHORT).show();
			}
		}

		// startActivity(Intent.createChooser(intent,
		// getString(R.id.btn_share)));
		// startActivity(shareIntent);
	}

	private void shareToSina() {

	}

	private void showLines() {
		String[] lines = new String[lineList.size()];
		for (int i = 0; i < lineList.size(); i++) {
			lines[i] = lineList.get(i).toString();
		}

		new AlertDialog.Builder(context).setTitle("请选择线路")
				.setItems(lines, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						prefs.edit()
								.putString(Utils.STOREDLINE,
										lineList.get(which).getName()).commit();
						prefs.edit().putBoolean(Utils.NEEDLOADLINE, false)
								.commit();
						urlString = lineList.get(which).getLink();
						getBusInfo();
						return;
					}
				}).show();
	}
}
